// Copyright (C) 2021 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the tests/LICENSE file.

import expect show *

// Tests that the hash-code field of string slices works.
// At some point the compiler wasn't allocating enough space and
//   allocating a new object would overwrite the hash code of string
//   slices.

main:
  hash_test
  equals_test

hash_test:
  str := "-In ancient times cats were worshipped as gods; they have not forgotten this."
  expected_hash := (str.copy 1).hash_code
  slice := str[1..]
  hash := slice.hash_code
  slice2 := str[1..]
  expect_equals expected_hash hash
  expect_equals expected_hash slice.hash_code
  expect_equals expected_hash slice2.hash_code
  new_object := [1, 2]
  expect_equals expected_hash hash
  expect_equals expected_hash slice.hash_code
  expect_equals expected_hash slice2.hash_code

equals_test:
  // Big enough that slices are real slices and not copies.
  str := """
      Now the number of mice is largely dependent, as every one knows, on the \
      number of cats; and Colonel Newman says, “Near villages and small towns I \
      have found the nests of humble-bees more numerous than elsewhere, which I \
      attribute to the number of cats that destroy the mice.” Hence it is quite \
      credible that the presence of a feline animal in large numbers in a \
      district might determine, through the intervention first of mice and then \
      of bees, the frequency of certain flowers in that district!"""
  ba := str.to_byte_array
  expect_equals ba DARWIN_COW_BYTE_ARRAY
  expect_not_equals str ba  // String and byte arrays do not equal each other.
  expect_not_equals ba str  // String and byte arrays do not equal each other.
  ba_slice1 := ba[3..ba.size - 3]
  ba_slice2 := ba[3..ba.size - 3]
  ba_copy1 := ba.copy 3 (ba.size - 3)
  ba_copy2 := ba.copy 3 (ba.size - 3)
  str_slice1 := str[3..str.size - 3]
  str_slice2 := str[3..str.size - 3]
  str_copy1 := str.copy 3 (str.size - 3)
  str_copy2 := str.copy 3 (str.size - 3)
  cow_slice1 := DARWIN_COW_BYTE_ARRAY[3..DARWIN_COW_BYTE_ARRAY.size - 3]
  cow_slice2 := DARWIN_COW_BYTE_ARRAY[3..DARWIN_COW_BYTE_ARRAY.size - 3]
  cow_copy1 := DARWIN_COW_BYTE_ARRAY.copy 3 (DARWIN_COW_BYTE_ARRAY.size - 3)
  cow_copy2 := DARWIN_COW_BYTE_ARRAY.copy 3 (DARWIN_COW_BYTE_ARRAY.size - 3)

  BYTE_ARRAYS := [ba_slice1, ba_slice2, ba_copy1, ba_copy2, cow_slice1, cow_slice2, cow_copy1, cow_copy2]
  STRINGS := [str_slice1, str_slice2, str_copy1, str_copy2]
  BYTE_ARRAYS.do:
    expect it is ByteArray
  STRINGS.do:
    expect it is string
  ALL := BYTE_ARRAYS + STRINGS
  ALL.do: | left |
    ALL.do: | right |
      if (left is string) != (right is string):
        expect_not_equals left right
      else:
        expect_equals left right

DARWIN_COW_BYTE_ARRAY ::= #[
    0x4e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f,
    0x66, 0x20, 0x6d, 0x69, 0x63, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x6c,
    0x79, 0x20, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x73, 0x20,
    0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x73, 0x2c,
    0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f,
    0x66, 0x20, 0x63, 0x61, 0x74, 0x73, 0x3b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x6f, 0x6c, 0x6f,
    0x6e, 0x65, 0x6c, 0x20, 0x4e, 0x65, 0x77, 0x6d, 0x61, 0x6e, 0x20, 0x73, 0x61, 0x79, 0x73, 0x2c,
    0x20, 0xe2, 0x80, 0x9c, 0x4e, 0x65, 0x61, 0x72, 0x20, 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x67, 0x65,
    0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x77, 0x6e,
    0x73, 0x20, 0x49, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x74,
    0x68, 0x65, 0x20, 0x6e, 0x65, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x68, 0x75, 0x6d, 0x62,
    0x6c, 0x65, 0x2d, 0x62, 0x65, 0x65, 0x73, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x6e, 0x75, 0x6d,
    0x65, 0x72, 0x6f, 0x75, 0x73, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x77,
    0x68, 0x65, 0x72, 0x65, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x49, 0x20, 0x61, 0x74,
    0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e,
    0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x61, 0x74, 0x73, 0x20, 0x74, 0x68,
    0x61, 0x74, 0x20, 0x64, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d,
    0x69, 0x63, 0x65, 0x2e, 0xe2, 0x80, 0x9d, 0x20, 0x48, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x74,
    0x20, 0x69, 0x73, 0x20, 0x71, 0x75, 0x69, 0x74, 0x65, 0x20, 0x63, 0x72, 0x65, 0x64, 0x69, 0x62,
    0x6c, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x73,
    0x65, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x66, 0x65, 0x6c, 0x69, 0x6e, 0x65,
    0x20, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65,
    0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x64, 0x69,
    0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x20, 0x6d, 0x69, 0x67, 0x68, 0x74, 0x20, 0x64, 0x65, 0x74,
    0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20,
    0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e,
    0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x69, 0x63, 0x65, 0x20, 0x61,
    0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x65, 0x65, 0x73, 0x2c,
    0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x20, 0x6f,
    0x66, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x77, 0x65, 0x72,
    0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69,
    0x63, 0x74, 0x21]

